#if !defined(__APP_BUFF_H)
#define __APP_BUFF_H
#include <stdio.h>
#include <sys/types.h>
#include "log.h"
#include <string.h>
#include <stdlib.h>
#include <pthread.h>

// 子缓冲区结构体
typedef struct 
{
    char * data; // 数据指针
    int len; // 当前数据长度
    int total_size; // 总长度
}sub_buffer_t;

// 主缓冲区结构体
typedef struct 
{
    sub_buffer_t *sub_buffer[2];
    int red_index;
    int write_index;
    pthread_mutex_t read_lock;
    pthread_mutex_t swap_lock;
}buffer_t;

/**
 * @brief 缓冲区的初始化
 * @param total_size 缓冲区总大小 因为是双缓冲结构 所以总大小为2倍
 * @return buffer_t* 缓冲区指针
 * @note 创建两个缓冲区，放入主缓冲区结构体，然后返回
 */
buffer_t * app_buff_init(int total_size);

/**
 * @brief 向缓冲区写入数据
 * @param buff 缓冲区指针
 * @param data 写入的数据指针
 * @param len 写入的数据长度
 * @return int 写入成功返回写入长度，失败返回-1
 * @note 判断是否可以写入数据 比较写入长度和剩余空间 \
 * 如果可以写入数据，则向尾部拷贝数据，更新当前缓冲区长度
 */
int app_buff_write(buffer_t * buff, char * data, u_int8_t len);

/**
 * @brief 从缓冲区读取数据
 * @param buffer 缓冲区指针
 * @param r_buff 读取的数据指针 （已经开辟空间）
 * @param buff_len 读取的数据长度
 * @return int 实际读取数据的长度
 * @note 判断容器是否够放一条数据，比较容器长度和数据长度 \
 * 判断当前读缓冲是否为空 要做切换。从缓冲区开头位置读取一条数据 \
 * 要从缓冲区删除数据，更新当前缓冲区长度。如果缓冲区为空，则切换缓冲区。
 */
int app_buff_read(buffer_t * buffer, char * r_buff, int buff_len);

/**
 * @brief 销毁缓冲区
 * @param buffer 缓冲区指针
 * @note 先释放子缓冲区指针，再释放主缓冲区指针
 */
void app_buff_destroy(buffer_t * buffer);

#endif